package com.chuangjiangx.member.manager.basic.web.config;

import com.chuangjiangx.commons.SpringContext;
import com.chuangjiangx.dddbase.spring.SpringDomainRegistry;
import com.chuangjiangx.member.manager.basic.web.interceptor.CrossInterceptor;
import com.chuangjiangx.member.manager.basic.web.interceptor.LoginInterceptor;
import com.chuangjiangx.member.manager.basic.web.interceptor.PermissionsInterceptor;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.hibernate.validator.HibernateValidator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * @author 陈智
 * @date 2018/6/28
 */
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor());
        registry.addInterceptor(permissionsInterceptor());
        registry.addInterceptor(crossInterceptor());
        super.addInterceptors(registry);
    }

    @Bean
    CrossInterceptor crossInterceptor() {
        return new CrossInterceptor();
    }

    @Bean
    public LoginInterceptor loginInterceptor() {
        return new LoginInterceptor();
    }

    @Bean
    public PermissionsInterceptor permissionsInterceptor() {
        return new PermissionsInterceptor();
    }



    /**
     * 配置过滤器encodingFilterRegistration
     */
    @Bean
    public FilterRegistrationBean encodingFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(encodingFilter());
        registration.addUrlPatterns("/*");
        registration.setName("encodingFilter");
        registration.setOrder(2);
        return registration;
    }

    /**
     * 创建一个bean：encodingFilter
     */
    @Bean(name = "encodingFilter")
    public Filter encodingFilter() {
        return new CharacterEncodingFilter("UTF-8", true);
    }


//    /**
//     * 配置过滤器clientApiLogFilterRegistration
//     */
//    @Bean
//    public FilterRegistrationBean clientApiLogFilterRegistration() {
//        FilterRegistrationBean registration = new FilterRegistrationBean();
////        registration.setFilter(clientApiLogFilter());
//        registration.addUrlPatterns("/*");
//        registration.setName("clientApiLogFilter");
//        registration.setOrder(3);
//        registration.addInitParameter("STORAGE_CACHE_SIZE", "10");
//        registration.addInitParameter("STORAGE_MODE", "1");
//        return registration;
//    }


//    /**
//     * 创建一个bean：clientApiLogFilter
//     */
//    @Bean(name = "clientApiLogFilter")
//    public Filter clientApiLogFilter() {
//        return new ClientApiLogFilter();
//    }


    /**
     * jackson配置
     * @return
     */
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
//        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        return mapper;
    }

    @Bean
    public XmlMapper xmlMapper() {
        XmlMapper mapper = new XmlMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper;
    }

    /**
     * 上传文件的解析器
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大KB,MB
        factory.setMaxFileSize("100MB");
        //设置总上传数据总大小
        factory.setMaxRequestSize("200MB");
        //设置上传临时目录
        String location = System.getProperty("user.dir") + "/tmp/upload";
        File tmpFile = new File(location);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }
        factory.setLocation(location);
        return factory.createMultipartConfig();
    }

    /**
     * 验证器
     */
    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
        validator.setProviderClass(HibernateValidator.class);
        return validator;
    }

    @Bean("springDomainRegistry")
    public SpringDomainRegistry springDomainRegistry(){
        return new SpringDomainRegistry();
    }

    /**
     * 会员模块引用
     * @return
     */
    @Bean
    public SpringContext springContext(){
        return new SpringContext();
    }


    /**
     * json和对象转换 转换LocalDateTime LocalDate LocalTime
     * @return
     */
    @Bean(name = "mapperObject")
    public ObjectMapper getObjectMapper() {
        ObjectMapper om = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        om.registerModule(javaTimeModule);
        //设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return om;
    }

}
